/**********************************************************************/
/**  Copyright (c) ECC labs. 2001-2002. All Rights Reserved.		 **/
/**********************************************************************/
/*
	binmatr.h
	Mark Papazyan

*/

#ifndef __CBINMATRIX_H
#define __CBINMATRIX_H

#include "binword.h"
#include "flags.h"


class CBinMatrix{
public:

//Variables

	t_len k, n;
	int flag;
	int base;

	CBinWord* row;
	CBinWord* col;

	t_len tr[2] ;

	struct t_prmut {
		int* s ;
		long* flag ;
	} ;

	int pos, pos1 ;
	t_prmut dat ;

//Constructors/Destructors

	CBinMatrix(t_len k=MAX_LENGTH, t_len n=MAX_HEIGHT, int flag=ROW, int base=BIN);
	CBinMatrix(const CBinMatrix&);
	~CBinMatrix();
	CBinMatrix& operator=(const CBinMatrix&);	

//Manipulation

	void trans();
	void row2col();		
	void col2row();			
	void cyclic_shift(t_len, char where='r'); 
	t_res edin(char ch='l');
	CBinWord col_gaus();
	CBinWord gaus();				
	t_src gaus1();
	t_src col_step();

//Permutations
	void mixer();
	void print();
	t_res next();
	inline void transp();
	t_res col_swap(); 
	t_res swap();


//Operations

	CBinMatrix& operator+=(CBinMatrix&);
	CBinMatrix operator+(CBinMatrix&);	

	CBinWord operator*(CBinWord&);	
	CBinWord operator*(t_src);

	CBinMatrix& operator*=(CBinMatrix&);	
	CBinMatrix operator*(CBinMatrix&);

	CBinMatrix& operator^=(CBinMatrix&);	
	CBinMatrix operator^(CBinMatrix&);

	CBinMatrix& operator^=(CBinWord&);
	CBinMatrix operator^(CBinWord&);

//Manipulation with flag

	void set_row();
	void set_col();
	void set_hcol();
	void set_base(int);
};

//Input/Output

ostream& operator<<(ostream&, CBinMatrix&);
istream& operator>>(istream&, CBinMatrix&);

void add_mat(CBinMatrix&, CBinMatrix&, CBinMatrix&);
void mul_mat(CBinMatrix&, CBinMatrix&, CBinMatrix&);
void mul_vec(CBinWord&, CBinMatrix&, CBinWord&);
void tmul_mat(CBinMatrix&, CBinMatrix&, CBinMatrix&);
void tmul_vec(CBinMatrix&, CBinMatrix&, CBinWord&);
#endif
